package archive

import (
	"archive/tar"
	"compress/gzip"
	"context"
	"github.com/cheggaaa/pb/v3"
	"io"
	"os"
	"path/filepath"
)

// DecompressGzipPackageFile 解压tar.gz文件
func DecompressGzipPackageFile(ctx context.Context, file *os.File, size int64, target string) error {
	var progress = pb.Full.Start64(size)
	defer progress.Finish()

	gr, err := gzip.NewReader(progress.NewProxyReader(file))
	if nil != err {
		return err
	}

	defer func() {
		_ = gr.Close()
	}()

	var tr = tar.NewReader(gr)
	for hdr, err := tr.Next(); io.EOF != err; hdr, err = tr.Next() {
		if nil != err {
			return err
		}

		if nil != ctx.Err() {
			return ctx.Err()
		}

		if err := os.MkdirAll(filepath.Join(target, filepath.Dir(hdr.Name)), 0755); nil != err {
			return err
		}

		if hdr.FileInfo().IsDir() {
			continue
		}

		if tar.TypeLink == hdr.Typeflag || tar.TypeSymlink == hdr.Typeflag {
			if err := os.Symlink(hdr.Linkname, filepath.Join(target, hdr.Name)); nil != err {
				return err
			}

			continue
		}

		f, err := os.OpenFile(filepath.Join(target, hdr.Name), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, hdr.FileInfo().Mode())
		if nil != err {
			return err
		}

		if _, err := io.Copy(f, tr); nil != err {
			return err
		}

		_ = f.Close()
	}

	return nil
}
